#include "depot.h"

Depot::Depot(const QString &name,const QStringList &standardValSymbols, QObject *parent):
    TradeHandler(parent),DepotConfig(name,standardValSymbols)
{
    /*add dummy standard values to list*/
    for(int i=0;i<getStdValSymbols().count();i++)
        standardVals.insert(getStdValSymbols().at(i),new QStandardItem());

    /*create new stock instance for this depot, load no stocks to use the already loaded stocks*/
    stocks=new Stock(*Global::getStockInstance());
}

Depot::Depot(const QString& name,const QStringList &standardValSymbols, const QStringList &standardValues, QObject *parent):
    TradeHandler(parent),DepotConfig(name,standardValSymbols)
{
    QMap<QString,QStandardItem*>::iterator iter;

    /*add standardValSymbols with standardValues to map*/
    if(getStdValSymbols().count()==standardValues.count())  //bijective
    {
        for(int i=0;i<getStdValSymbols().count();i++)
        {
            iter=standardVals.insert(getStdValSymbols().at(i),new QStandardItem()); //insert a new item
            iter.value()->setData(QVariant(standardValues.at(i)));                  //fill item with the value
        }
    }
    /*create new stock instance for this depot, load no stocks to use the already loaded stocks*/
    stocks=new Stock(*Global::getStockInstance());
}

Depot::Depot(const QString& name,const QStringList &standardValSymbols, const QList<QVariant> &standardValues, QObject *parent):
    TradeHandler(parent),DepotConfig(name,standardValSymbols)
{
    QMap<QString,QStandardItem*>::iterator iter;

    /*add standardValSymbols with standardValues to map*/
    if(getStdValSymbols().count()==standardValues.count())  //bijective
    {
        for(int i=0;i<getStdValSymbols().count();i++)
        {
            iter=standardVals.insert(getStdValSymbols().at(i),new QStandardItem());
            iter.value()->setData(standardValues.at(i));
        }
    }

    /*create new stock instance for this depot, load no stocks to use the already loaded stocks*/
    stocks=new Stock(*Global::getStockInstance());
}

/*sets the value at position index*/
void Depot::setStandardValue(const QString& key,const QVariant &val, int flag)
{
    qDebug()<<"Depot::setSatndardValue(): "<<"Set standard value "<<key<<"="<<val;
    /*set value of the specific key*/
    standardVals.find(key).value()->setData(val);

    /*standard value changed by a trade (e.g. the current liquidity changed by a trade)*/
    if(flag==SET_BY_TRADE)
    {
        qDebug()<<"Depot::setStandardValue(): "<<"emit signal standardValueChanged";
        emit standardValueChanged(getDepotName(),key,val.toString());
        updateValue(DEPOT_TABLE_NAME,key,val.toString(),QString(DEPOT_TABLE_NAME_FIELD)+"='"+getDepotName()+"'");
    }
}

/*sets the given map to the depot map*/
void Depot::setStandardValue(const QMap<QString, QVariant> &vals)
{
    QMap<QString,QVariant>::const_iterator cIter;

    /*set the values of the map to the depot map*/
    for(cIter=vals.begin();cIter!=vals.end();++cIter)
        setStandardValue(cIter.key(),cIter.value());
}

void Depot::setStandardValues(const QMap<QString, QStandardItem *> &vals)
{
    standardVals=vals;
}

QVariant Depot::getStandardValue(const QString &key)
{
    return standardVals.value(key)->data();
}

QMap<QString,QStandardItem*> Depot::getStandardValues()const
{
    return standardVals;
}

QMap<QString, QVariant> Depot::getStandardValuesVar()
{
    QMap<QString,QVariant> vars;
    QMap<QString,QStandardItem*>::iterator iter;
    for(iter=standardVals.begin();iter!=standardVals.end();++iter)
        vars.insert(iter.key(),iter.value()->data());
    return vars;
}

void Depot::setStocks(Stock *stocks)
{
    this->stocks=stocks;
}

Stock* Depot::getStocks()
{
    return stocks;
}

Depot& Depot::operator =(const Depot& other)
{
    setStandardValues(other.getStandardValues());
    //setStocks(other.getStocks());
    return *this;
}

QMap<QString,QVariant> Depot::loadStdValues()
{
    QMap<QString,QVariant>  dbRowValues;
    QStringList whereClause;

    /*get row values for the current depotName from the standard depot table*/
    whereClause<<DEPOT_TABLE_NAME_FIELD<<"='"<<getDepotName()<<"'";
    dbRowValues=getRow(DEPOT_TABLE_NAME,getStdValSymbols(),whereClause.join(""));
    qDebug()<<"Depot::loadStdValues(): "<<"Setup standard values";

    return dbRowValues;
}

QList<QMap<QString,QVariant> > Depot::loadDepotStocks()
{
    /*load saved depot stocks (first valSymbol has to be the STOCKID-field!)*/
    QStringList fields;
    fields<<getDepotValSymbols()<<STOCK_NAME_FIELD;   //fields to read
    /*load the stocks stored in the depot and the values belonging to the stocks from the stock table*/
    QList<QMap<QString,QVariant> > depotStocks;
    depotStocks=getInnerJoinValues(getDepotTableName(),STOCK_TABLE,getDepotValSymbols().first(),"ID",fields);

    return depotStocks;
}

void Depot::init(Config *cfg, int flag)
{
    /*add the new values to standard depot table*/
    if(flag==STORE_DEPOT_STD_VALUES)
    {
        addValues(DEPOT_TABLE_NAME,getStandardValuesVar());
        qDebug()<<"Depot::init(): "<<"standard values added";
    }

    /*load standard values of the depot*/
    setStandardValue(loadStdValues());
    qDebug()<<"Depot::init(): "<<"Standard values set";

    /*create depot table for the stocks of the depot, if it does not exist*/
    addTable(getDepotTableName(),getDepotValSymbols());
    qDebug()<<"Depot::init(): "<<"Depot table created";

    /*load the stocks stored in the depot and the values belonging to the stocks from the stock table*/
    QList<QMap<QString,QVariant> > depotStocks(loadDepotStocks());

    //add the loaded stocks to the depot to show them in the stock table view
    for(int z=0;z<depotStocks.count();z++)
    {
        QString tmpStockName=depotStocks.at(z).value(STOCK_NAME_FIELD).toString();          //stock name
        /*add stock name to map and emit signal to tableview, don't save it to db*/
        stocks->addStock(tmpStockName,ADD_STOCK_NAME);
    }

    setConfig(cfg);                                 //set the config file
    setTableName(getDepotTableName()+"_TRADES");    //set the table name, where all trades of the depot are stored
    TradeHandler::init();                           //init the tradehandler*/
}

void Depot::addStock(const QString& stockName)
{
    /*Add specific stock values to the depot table*/
    QStringList values;
    int primKey=getPrimaryKey(STOCK_TABLE,STOCK_NAME_FIELD,stockName);  //get the primary key(ID) of the new stock

    /*Pay attention to the order of the depot value symbols*/
    /*stockID - Profit*/
    values<<QString("%1").arg(primKey)<<"0";                                //build value list
    addValues(getDepotTableName(),getDepotValSymbols(),values);             //add stock to depot table
    values.clear();                                                         //clear value list

    //TODO: Look for a better way, to get the primary key!
    /*get the primary key of the stored stock entry and store it with the other trade values in the trade table*/
    /*stockID - amount - buyDate - sellDate - ...*/
    values<<QString("%1").arg(primKey)                                                  //stock id
            <<"0"                                                                       //amount
            <<QDate().currentDate().toString("dd.MM.yyyy")                              //buy date
            <<"0"                                                                       //sell date
            <<"0"                                                                       //?
            <<stocks->getValue(stocks->getStockSymbolByName(stockName),"l10")->text()   //ask
            <<standardVals.value(DEPOT_TABLE_STANDARDPROVISION_FIELD)->data().toString()//standard provision
            <<"0"
            <<"0";
    addTrade(stockName,values,SHOW_BUY_DIALOG);//add a new trade for the new stock by showing the trade buy dialog
}

double Depot::getCurrentLiquidity()
{
    return getStandardValue(DEPOT_TABLE_CURRENT_LIQUIDITY_FIELD).toDouble();   //current liquidity
}

void Depot::setCurrentLiquidity(const qreal &liq)
{
    setStandardValue(DEPOT_TABLE_CURRENT_LIQUIDITY_FIELD,liq,SET_BY_TRADE);   //set new current liquidity
}
